1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 */
6 module code_checker.engine.types;
7 
8 public import my.path : AbsolutePath;
9 
10 public import code_checker.cli : Config;
11 
12 @safe:
13 
14 /** The base fixture that an analyzer implement
15  */
16 interface BaseFixture {
17     /// the name of the analyser.
18     string name();
19 
20     /// Explain what the analyser is.
21     string explain();
22 
23     /// The environment the analysers execute in.
24     void putEnv(Environment);
25 
26     /// Setup the environment for analyze.
27     void setup();
28 
29     /// Execute the analyser.
30     void execute();
31 
32     /// Cleanup after analyze.
33     void tearDown();
34 
35     /// Returns: the result of the analyzer.
36     Result result();
37 }
38 
39 /// Environment data useful for an anylser.
40 struct Environment {
41     import my.path : AbsolutePath;
42     import compile_db : CompileCommandDB, CompileCommandFilter;
43 
44     Config conf;
45 
46     /// The compile_commands.json that contains all files to analyse.
47     AbsolutePath compileDbFile;
48 
49     /// The compile commands that is used for the analyse.
50     CompileCommandDB compileDb;
51 
52     /// The files to analyse.
53     string[] files;
54 }
55 
56 /// The summary of an analyzers result.
57 enum Status {
58     none,
59     /// The analyze failed
60     failed,
61     /// The analyze passed without any remarks.
62     passed
63 }
64 
65 Status mergeStatus(Status old, Status new_) @safe pure nothrow @nogc {
66     if (old == Status.none)
67         return new_;
68     return old == Status.failed ? old : new_;
69 }
70 
71 /// The amount of points the analyzer adjusts the overall score
72 struct Score {
73     int value;
74     alias value this;
75 }
76 
77 /// The number of suppressed warnings from a static code analyzer.
78 struct Suppressed {
79     int value;
80     alias value this;
81 }
82 
83 /// The severity of a user message.
84 enum MsgSeverity {
85     /// Why an analyzer failed to execute
86     unableToExecute,
87     /// Why an analyzer reports failed
88     failReason,
89     /// Improvement suggestions for how to fix the score intended for the user
90     improveSuggestion,
91     /// Trace data that should only be printed when the loglevel is trace
92     trace,
93 }
94 
95 /// A message from an analyzer.
96 struct Msg {
97     MsgSeverity severity;
98     string value;
99     alias value this;
100 
101     int opCmp(ref const Msg rhs) @safe pure nothrow const {
102         if (severity < rhs.severity)
103             return -1;
104         else if (severity > rhs.severity)
105             return 1;
106         else
107             return value < rhs.value ? -1 : (value > rhs.value ? 1 : 0);
108     }
109 
110     bool opEquals(ref const Msg o) @safe pure nothrow const @nogc scope {
111         return severity == o.severity && value == o.value;
112     }
113 
114     string toString() @safe const {
115         import std.format : format;
116 
117         return format("%s: %s", severity, value);
118     }
119 }
120 
121 /// Messages from an analyzer intended to be displayed to the user.
122 struct Messages {
123     Msg[] value;
124     alias value this;
125 }
126 
127 /// Suggestions of how to improve the score.
128 struct Suggestions {
129     Msg[] value;
130     alias value this;
131 }
132 
133 /// The result of an analyzer.
134 struct Result {
135     /// The summary state of an analyzer after it has executed.
136     Status status;
137 
138     Score score;
139 
140     Messages msg;
141 
142     /// Warnings suppressed by the user.
143     Suppressed supp;
144 
145     /// Files that failed an analyze.
146     AbsolutePath[] failed;
147 
148     /// Files that passed all analyzers.
149     AbsolutePath[] success;
150 }
151 
152 /// The result of all analyzers.
153 struct TotalResult {
154     /// Total status of all analyzers
155     Status status;
156 
157     /// Total score of the analyzers
158     Score score;
159 
160     /// Improvement suggestions for the user
161     Suggestions sugg;
162 
163     /// Warnings suppressed by the user.
164     Suppressed supp;
165 
166     /// Files that failed an analyze.
167     AbsolutePath[] failed;
168 
169     /// Files that passed all analyzers.
170     AbsolutePath[] success;
171 }
172 
173 /// Classification of warnings. Used by the user to filter on.
174 /// This enum must be ordered such that style < low < medium < high < critical
175 enum Severity {
176     style,
177     low,
178     medium,
179     high,
180     critical
181 }
182 
183 /// Returns: a nullable severity translation from a string.
184 auto toSeverity(string s) @safe pure nothrow {
185     import std.typecons : Nullable;
186     import std.conv : to;
187 
188     Nullable!Severity r;
189 
190     try {
191         r = s.to!Severity;
192     } catch (Exception e) {
193     }
194 
195     return r;
196 }